home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #2 / Monster Media No. 2 (Monster Media)(1994).ISO / prog_c / pclc41.zip / XYPACKET.C < prev    next >
Text File  |  1994-01-07  |  10KB  |  337 lines

  1. /*** xypacket.c ***/
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <fcntl.h>
  5. #include <io.h>
  6. #include <sys\types.h>
  7. #include <sys\stat.h>
  8.  
  9. #include "pcl4c.h"
  10. #include "term.h"
  11. #include "crc.h"
  12. #include "ascii.h"
  13. #include "term_io.h"
  14. #include "term.cfg"
  15.  
  16. #define DEBUG 0
  17.  
  18. #define FALSE 0
  19. #define TRUE !FALSE
  20.  
  21. #define MAXTRY 5
  22. #define LIMIT 20
  23.  
  24. void PacketError(int ,int ,int ,char *);
  25.  
  26. int TxPacket(
  27.    int Port,            /* COM port [0..3] */
  28.    int PacketNbr,       /* Packet # to send */
  29.    int PacketSize,      /* Packet size ( must be 128 or 1024 ) */
  30.    char Buffer[],       /* Data buffer */
  31.    char NCGchar)        /* NAK, 'C', or 'G' */
  32. {int  i;
  33.  int Code;
  34.  unsigned short CheckSum;
  35.  int Attempt;
  36.  int PacketType;
  37.  char temp[81];
  38.  /* begin */
  39. #if DEBUG
  40. printf("[TxP: COM%d PacketNbr=%d PacketSize=%d NCGchar=%c]",
  41.     1+Port,PacketNbr,PacketSize,NCGchar);
  42. #endif
  43.  /* better be 128 or 1024 packet length */
  44.  if(PacketSize==1024) PacketType = STX;
  45.  else PacketType = SOH;
  46.  PacketNbr &= 0x00ff;
  47.  /* make up to MAXTRY attempts to send this packet */
  48.  for(Attempt=1;Attempt<=MAXTRY;Attempt++)
  49.      {/* send SOH/STX  */
  50.       Code = PutChar(Port,(char)PacketType);
  51.       /* send packet # */
  52.       Code = PutChar(Port,(char)PacketNbr);
  53.       /* send 1's complement of packet */
  54.       Code = PutChar(Port,(char)(255-PacketNbr));
  55.       /* send data */
  56.       CheckSum = 0;
  57.       for(i=0;i<PacketSize;i++)
  58.           {Code = PutChar(Port,Buffer[i]);
  59.            if(NCGchar==NAK) CheckSum += Buffer[i];
  60.            else CheckSum = UpdateCRC(CheckSum, Buffer[i]);
  61.           }
  62.       /* send checksum */
  63.       if(NCGchar==NAK)
  64.           {Code = PutChar(Port,(char)(CheckSum & 0x00ff) );
  65.           }
  66.       else
  67.           {Code = PutChar(Port, (char)((CheckSum>>8) & 0x00ff) );
  68.            Code = PutChar(Port, (char)(CheckSum & 0x00ff) );
  69.           }
  70.       /* no ACK to wait for if 'G' */
  71.       if(NCGchar=='G')
  72.          {if(PacketNbr==0) SioDelay(SHORT_WAIT*ONE_SECOND/2);
  73.           return(TRUE);
  74.          }
  75.       /* wait for receivers ACK */
  76.       Code = GetChar(Port,LONG_WAIT*ONE_SECOND);
  77.       if((char)Code==CAN)
  78.           {DisplayLine("*** Canceled by REMOTE ***",NULL,0);
  79.            return(FALSE);
  80.           }
  81.       if((char)Code==ACK) return(TRUE);
  82.       if((char)Code!=NAK)
  83.           {PacketError(Port,PacketNbr,Attempt,"Out of sync");
  84.            return(FALSE);
  85.           }
  86.       /* Attempt again */
  87.      }/* end -- for(Attempt) */
  88.  /* can't send packet ! */
  89.  SayError(Port,"packet timeout (3 NAKs)");
  90.  return(FALSE);
  91. } /* end -- TxPacket */
  92.  
  93. int RxPacket(
  94.    int Port,            /* COM port [0..3] */
  95.    int PacketNbr,       /* Packet # expected */
  96.    int *PacketSizePtr,  /* Pointer to PacketSize received ( 128 or 1024) */
  97.    char Buffer[],       /* 1024 byte data buffer */
  98.    char NCGchar,        /* NAK, C, or G */
  99.    int *EOTptr)         /* Pointer to EOT flag */
  100. {int i;
  101.  int Code;
  102.  int Attempt;
  103.  int RxPacketNbr;
  104.  int RxPacketNbrComp;
  105.  unsigned short CheckSum;
  106.  unsigned short RxCheckSum;
  107.  unsigned short RxCheckSum1, RxCheckSum2;
  108.  /*char PacketType;*/
  109.  char temp[81];
  110.  /* begin */
  111. #if DEBUG
  112. printf("[RxP: COM%d PacketNbr=%d NCGchar=%c EOTflag=%d]",
  113.     1+Port,PacketNbr,NCGchar,*EOTptr);
  114. #endif
  115.  PacketNbr &= 0x00ff;
  116.  for(Attempt=1;Attempt<=MAXTRY;Attempt++)
  117.      {/* wait for SOH / STX */
  118.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  119.       if(Code==-1)
  120.           {PacketError(Port,PacketNbr,Attempt,"timed out waiting for SOH/STX");
  121.            return(FALSE);
  122.           }
  123.       switch((char)Code)
  124.           {
  125.            case SOH:
  126.                /* 128 byte buffer incoming */
  127.                /*PacketType = SOH;*/
  128.                *PacketSizePtr = 128;
  129.                break;
  130.            case STX:
  131.                /* 1024 byte buffer incoming */
  132.                /*PacketType = STX;*/
  133.                *PacketSizePtr = 1024;
  134.                break;
  135.            case CAN:
  136.                 /* sender has canceled ! */
  137.                 DisplayLine("*** Canceled by REMOTE ***",NULL,0);
  138.                 return(FALSE);
  139.            case EOT:
  140.                 /* all packets have been sent */
  141.                 Code = PutChar(Port,ACK);
  142.                 *EOTptr = TRUE;
  143.                 return(TRUE);
  144.            default:
  145.                 /* error ! */
  146.                 sprintf(temp,"Expecting SOH/STX/EOT/CAN not %xH",(char)Code);
  147.                 PacketError(Port,PacketNbr,Attempt,temp);
  148.                 return(FALSE);
  149.           }
  150.       /* receive packet # */
  151.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  152.       if(Code==-1)
  153.         {PacketError(Port,PacketNbr,Attempt,"timed out waiting for packet number");
  154.          return(FALSE);
  155.         }
  156.       RxPacketNbr = 0x00ff & Code;
  157.       /* receive 1's complement */
  158.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  159.       if(Code==-1)
  160.         {PacketError(Port,PacketNbr,Attempt,"timed out waiting for complement of packet #");
  161.          return(FALSE);
  162.         }
  163.       RxPacketNbrComp = 0x00ff & Code;
  164.       /* verify packet number */
  165.       if(RxPacketNbr+RxPacketNbrComp!=255)
  166.           {PacketError(Port,PacketNbr,Attempt,"Bad packet number");
  167.            return(FALSE);
  168.           }
  169.       /* receive data */
  170.       CheckSum = 0;
  171.       for(i=0;i<*PacketSizePtr;i++)
  172.           {Code = GetChar(Port,LONG_WAIT*ONE_SECOND);
  173.            if(Code==-1)
  174.                    {PacketError(Port,PacketNbr,Attempt,"timed out waiting for data for packet #");
  175.                     return(FALSE);
  176.                    }
  177.            Buffer[i] = Code;
  178.            /* compute CRC or checksum */
  179.            if(NCGchar!=NAK) CheckSum = UpdateCRC(CheckSum,(unsigned char)Code);
  180.            else CheckSum = (CheckSum + Code) & 0x00ff;
  181.           }
  182.       /* receive CRC/checksum */
  183.       if(NCGchar!=NAK)
  184.           {/* receive 2 byte CRC */
  185.            Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  186.            if(Code==-1)
  187.                    {PacketError(Port,PacketNbr,Attempt,"timed out waiting for 1st CRC byte");
  188.                     return(FALSE);
  189.                    }
  190.            RxCheckSum1 = Code & 0x00ff;
  191.            Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  192.            if(Code==-1)
  193.                    {PacketError(Port,PacketNbr,Attempt,"timed out waiting for 2nd CRC byte");
  194.                     return(FALSE);
  195.                    }
  196.            RxCheckSum2 = Code & 0x00ff;
  197.            RxCheckSum = (RxCheckSum1<<8) | RxCheckSum2;
  198.           }
  199.       else
  200.           {/* receive one byte checksum */
  201.            Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  202.            if(Code==-1)
  203.                    {PacketError(Port,PacketNbr,Attempt,"timed out waiting for checksum");
  204.                     return(FALSE);
  205.                    }
  206.            RxCheckSum = Code & 0x00ff;
  207.           }
  208.       /* don't send ACK if 'G' */
  209.       if(NCGchar=='G') return(TRUE);
  210.       /* checksum OK ? */
  211.       if(RxCheckSum!=CheckSum)
  212.           {DisplayLine("Bad packet checksum",NULL,0);
  213.            Code = PutChar(Port,NAK);
  214. #if DEBUG
  215.   printf("RxPacket %d: Checksum: RX = %xH, Computed = %xH (%c)\n",
  216.         RxPacketNbr,RxCheckSum,CheckSum,NCGchar);
  217. #endif
  218.           }
  219.       /* packet number OK ? */
  220.       else if(RxPacketNbr!=PacketNbr)
  221.           {DisplayLine("Bad packet number",NULL,0);
  222.            Code = PutChar(Port,NAK);
  223.           }
  224.       else
  225.           {/* ACK the packet */
  226.            PutChar(Port,ACK);
  227.            return(TRUE);
  228.           } /* end if */
  229.      } /* end -- for(Attempt) */
  230.  /* can't receive packet */
  231.  SayError(Port,"RX packet timeout");
  232.  return(FALSE);
  233. } /* end -- RxPacket */
  234.  
  235. void PacketError(int Port, int Packet, int Attempt, char *MsgPtr)
  236. {char temp[81];
  237.  sprintf(temp,"Packet %d : Attempt %d : %s",Packet,Attempt,MsgPtr);
  238.  SayError(Port,temp);
  239. }
  240.  
  241. int TxStartup(int Port,char *NCGcharPtr)
  242. {int i;
  243.  int Code;
  244. #if DEBUG
  245.  printf("### TxStartup");
  246. #endif
  247.  /* clear Rx buffer */
  248.  SioRxFlush(Port);
  249.  /* wait for receivers start up NAK, 'C', or 'G' */
  250.  for(i=1;i<LIMIT;i++)
  251.      {if(SioKeyPress())
  252.           {SayError(Port,"Aborted by user");
  253.            return(FALSE);
  254.           }
  255.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  256.       if(Code==-1) continue;
  257.       /* received a byte */
  258.       if((char)Code==NAK)
  259.           {*NCGcharPtr = NAK;
  260. #if DEBUG
  261.            printf("(CS) OK\n");
  262. #endif
  263.            return(TRUE);
  264.           }
  265.       if((char)Code=='C')
  266.           {*NCGcharPtr = 'C';
  267. #if DEBUG
  268.            printf("(CRC) OK\n");
  269. #endif
  270.            return(TRUE);
  271.           }
  272.       if((char)Code=='G')
  273.           {*NCGcharPtr = 'G';
  274. #if DEBUG
  275.            printf("(G) OK\n");
  276. #endif
  277.            return(TRUE);
  278.           }
  279.      } /* end -- for(i) */
  280.  /* no response */
  281.  SayError(Port,"No response from receiver");
  282.  return(FALSE);
  283. } /* end -- TxStartup */
  284.  
  285.  
  286. int RxStartup(int Port,char *NCGcharPtr)
  287. {int i;
  288.  int Code;
  289. #if DEBUG
  290.  printf("### RxStartup");
  291.  printf(" %c[%xH]\n",*NCGcharPtr,*NCGcharPtr);
  292. #endif
  293.  /* clear Rx buffer */
  294.  SioRxFlush(Port);
  295.  /* Send NAKs, 'C's, or 'G's */
  296.  for(i=1;i<LIMIT;i++)
  297.      {if(SioKeyPress())
  298.           {DisplayLine("*** Canceled by USER ***",NULL,0);
  299.            return(FALSE);
  300.           }
  301.       /* stop attempting CRC/'G' after 1st 4 tries */
  302.       if((*NCGcharPtr!=NAK)&&(i==5))
  303.          {*NCGcharPtr = NAK;
  304. #if DEBUG
  305. printf("<changing to NAKs>");
  306. #endif
  307.          }
  308.       /* tell sender that I am ready to receive */
  309.       Code = PutChar(Port,*NCGcharPtr);
  310. #if DEBUG
  311. printf("<%c>",*NCGcharPtr);
  312. #endif
  313.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  314.       if(Code==-1) continue;
  315.       /* no error -- must be incoming byte -- push byte back onto queue ! */
  316.       SioUnGetc(Port,(char)Code);
  317. #if DEBUG
  318.       printf("OK\n");
  319. #endif
  320.       return(TRUE);
  321.      } /* end -- for(i) */
  322.  /* no response */
  323.  SayError(Port,"No response from sender");
  324.  return(FALSE);
  325. } /* end -- RxStartup */
  326.  
  327. int TxEOT(int Port)
  328. {int i;
  329.  int Code;
  330.  for(i=0;i<10;i++)
  331.      {Code = PutChar(Port,EOT);
  332.       /* await response */
  333.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  334.       if((char)Code==ACK) return(TRUE);
  335.      } /* end -- for(i) */
  336.   return(FALSE);
  337.  } /* end -- TxEOT */